﻿//Author:Michal Sporna
//License: https://operationsneakpeek.codeplex.com/license

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Levels
{
    /// <summary>
    /// represents one map cell
    /// </summary>
    public class MapCell
    {
        #region properties
        //ID of the map cell
        public string ID; //eg: A1
        public double Minutes;//time before bombs go off
        public int Energy;
        //list of obstacles for the current grid
        public List<Util.Classes.ObstacleToDraw> Obstacles;
        //list of textures to draw
        public List<Util.Classes.TextureToDraw> TexturesToDraw;
        //list of portals
        //public List<Portal> Portals { get; set; }
        //list of move patterns for NPC that are in this map cell
        public List<Characters.Helpers.MovePattern> MovePatterns;
        //list of NPCs for this map cell
        public List<Characters.NPC> NPCs;
        //list of requirements for the map cell
        public List<Requirement> Requirements;
        //list of bombs in that map cell
        public List<Util.Classes.BombToDraw> Bombs;
        //list of items in that map cell
        public List<Util.Classes.ItemToDraw> CollectableItems;
        //portals
        public List<Portal> Portals;
        //avatar placement
        public List<AvatarPlacement> AvatarPlacement;
        //Markers to draw
        public List<World.Classes.Marker> MarkersToDraw;
      
        

        //does the map cell has any trackable bombs
        public bool HasAnyTrackableBombs;
        public bool LettersPlaced; //if letters placed then set to true 
        public bool NPCsSet;
        #endregion

        #region private
        private bool _MarkerTexturesObtained;
        private Texture2D _GreenMarkerTexture = null;
        private Texture2D _OrangeMarkerTexture = null;
        private Texture2D _RedMarkerTexture = null;
        
        //map cell:
        
        #endregion


        #region draw

        /// <summary>
        /// draw current map cell
        /// </summary>
        /// <returns></returns>
        public bool DrawCell()
        {
           

            try
            {
                if (World.MapScanner.IsShown)
                {
                    //do not draw the cell if map scanner is shown
                    return true;
                }

                //draw textures
                foreach (Util.Classes.TextureToDraw ttd in this.TexturesToDraw)
                {
                    //set texture
                    if (!ttd.TextureSet)
                    {
                        ttd.TextureInstance = Util.Cache.GetTexture(ttd.Texture.ToLower()).Text2D;
                        ttd.TextureSet = true;
                       
                    }

                    Util.Cache.Draw(ttd.TextureInstance, new int[]{ttd.X, ttd.Y, ttd.Width, ttd.Height}, Color.White);
                }

                //don't draw obstacles if bomb is being defused
                if (!World.WorldManager.IsDefusingBomb)
                {
                   

                    #region obstacles
                    //draw obstacles
                    foreach (Util.Classes.ObstacleToDraw otd in this.Obstacles)
                    {
                        

                        //texture
                        //set
                        if (!otd.TextureSet)
                        {
                            otd.TextureInstance = Util.Cache.GetTexture(otd.TextureName).Text2D;
                            otd.TextureSet = true;
                        
                        }


                        Util.Cache.Draw(otd.TextureInstance, new int[]{(int)otd.Position.X, (int)otd.Position.Y, otd.Dimensions[0],otd.Dimensions[1]}, Color.White);

                        //what state?
                        //switch (otd.CurrentState)
                        //{
                        //    case 0:
                        //        {
                        //            //regular state
                        //            Util.Cache.Draw(otd.TextureInstance, new Rectangle((int)otd.Position.X, (int)otd.Position.Y, o.Width, o.Height), Color.White);
                        //            break;
                        //        }
                        //    case 1:
                        //        {
                        //            //state2
                        //            Util.Cache.Draw(otd.TextureInstance, new Rectangle((int)otd.Position.X, (int)otd.Position.Y, o.Width, o.Height), Color.White);

                        //            break;
                        //        }

                        //}
                    

                        #region draw interactive icon, if this obstacle is interactive

                        if (otd.Interactive)
                        {
                            //draw an icon next to the obstacle
                            //draw it active if avatar is near,draw it inactive if avatar is far
                            if (otd.IsAvatarNearTheObstacle())
                            {
                                //set active
                                otd.ToolIcon.IsActive = true;
                            }
                            else
                            {
                                //set inactive
                                otd.ToolIcon.IsActive = false;
                            }

                            //draw tool icon
                            otd.ToolIcon.Draw();
                        }




                        #endregion

                    }

                    #endregion

                    #region items

                    //draw items
                        for (int ii = 0; ii < this.CollectableItems.Count; ii++)
                        {
                           

                            if (!this.CollectableItems[ii].TextureSet)
                            {
                                this.CollectableItems[ii].TextureInstance = Util.Cache.GetTexture(this.CollectableItems[ii].TextureName).Text2D;
                                this.CollectableItems[ii].TextureSet = true;
                                
                            }

                            //draw
                            Util.Cache.Draw(this.CollectableItems[ii].TextureInstance, new int[]{(int)this.CollectableItems[ii].Position.X, (int)this.CollectableItems[ii].Position.Y, this.CollectableItems[ii].Dimensions[0], this.CollectableItems[ii].Dimensions[1]}, Color.White);


                            #region avatar is getting the item?
                            //check if avatar walked on that item, meaning he collected it
                            this.CollectableItems[ii].IsAvatarGettingThisItem();

                            #endregion

                        }


                        

                    #endregion

                    #region portals

                        for (int pI = 0; pI < this.Portals.Count; pI++)
                        {
                            //create portal rectangle,
                            //if not yet created
                            if (!this.Portals[pI].RectPreapared)
                            {
                                this.Portals[pI].CreateRectangle();
                            }

                            //draw
                            this.Portals[pI].Draw();
                        }

                    #endregion

                }

            

                return true;
            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return false;
            }


        }

        /// <summary>
        /// draw markers to draw
        /// </summary>
        public void DrawMarkersToDraw()
        {
            try
            {
                #region markers

                //obtain marker texture once
                if (!_MarkerTexturesObtained)
                {
                    _GreenMarkerTexture = Util.Cache.GetTexture("GreenMarker").Text2D;
                    _OrangeMarkerTexture = Util.Cache.GetTexture("OrangeMarker").Text2D;
                    _RedMarkerTexture = Util.Cache.GetTexture("RedMarker").Text2D;

                    _MarkerTexturesObtained = true;
                }

                if (MarkersToDraw != null)
                {
                    for(int i=0;i<MarkersToDraw.Count;i++)
                    {
                        switch (MarkersToDraw[i].Type)
                        {
                            case Util.Helpers.PublicEnums.MarkerType.Green:
                                {
                                    Util.Cache.Draw(_GreenMarkerTexture, new Rectangle(MarkersToDraw[i].Rect[0], MarkersToDraw[i].Rect[1], World.WorldManager.WorldConfig.MarkerWidth, World.WorldManager.WorldConfig.MarkerHeight), Color.White);
                                    break;
                                }
                            case Util.Helpers.PublicEnums.MarkerType.Orange:
                                {
                                    Util.Cache.Draw(_OrangeMarkerTexture, new Rectangle(MarkersToDraw[i].Rect[0], MarkersToDraw[i].Rect[1], World.WorldManager.WorldConfig.MarkerWidth, World.WorldManager.WorldConfig.MarkerHeight), Color.White);
                                    break;
                                }
                            case Util.Helpers.PublicEnums.MarkerType.Red:
                                {
                                    Util.Cache.Draw(_RedMarkerTexture, new Rectangle(MarkersToDraw[i].Rect[0], MarkersToDraw[i].Rect[1], World.WorldManager.WorldConfig.MarkerWidth, World.WorldManager.WorldConfig.MarkerHeight), Color.White);
                                    break;
                                }
                        }
                    }
                }

                #endregion
            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }


        #endregion

        #region methods

        /// <summary>
        /// If item is collected, it is not required to draw it anymore
        /// so remove BY ID
        /// </summary>
        /// <param name="ID"></param>
        public void RemoveItemToDrawFromItems(string ID)
        {
            try
            {
                for (int i = 0; i < this.CollectableItems.Count; i++)
                {
                    if (this.CollectableItems[i].ItemID.ToLower().Trim() == ID.ToLower().Trim())
                    {
                        this.CollectableItems.RemoveAt(i);
                        break;
                    }
                }




            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// If item is collected, it is not required to draw it anymore
        /// so remove all that are collected=true
        /// </summary>
        /// <param name="ID"></param>
        public void RemoveItemToDrawFromItems()
        {
            try
            {
                for (int i = 0; i < this.CollectableItems.Count; i++)
                {
                    if (this.CollectableItems[i].Collected)
                    {
                        this.CollectableItems.RemoveAt(i);
                        
                    }
                }




            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// Return list of move patterns that
        /// are set for npc number x (uniqueID)
        /// so npc 1 gets move patterns with NPCCT 1
        /// and name of the npc is a match (eg. cartel member)
        /// </summary>
        /// <param name="uniqueID"></param>
        /// <returns></returns>
        public List<Characters.Helpers.MovePattern> GetMovePatternsByNPCUniqueID(int uniqueID, string npcID)
        {
            //declare
            List<Characters.Helpers.MovePattern> movePatterns = null ;

            try
            {
                movePatterns = new List<Characters.Helpers.MovePattern>();

                //process
                if (this.MovePatterns != null)
                {
                    foreach (Characters.Helpers.MovePattern movePattern in this.MovePatterns)
                    {
                        if (movePattern.NPCCT == uniqueID && movePattern.NPCID == npcID)
                        {
                            movePatterns.Add(movePattern);
                        }
                    }
                }


                return movePatterns;
            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return movePatterns;
            }
        }


        /// <summary>
        /// Prepare state2 of each obstacle:
        /// add obstacle to draw in state2, based on obstacle from available obstacles in each obstacle to draw
        /// that has state2
        /// </summary>
        public void PrepareState2OfObstacles()
        {
            //declare
            Util.Classes.ObstacleToolIcon toolIcon;
            Util.Classes.Obstacle o;

            try
            {
                for (int i = 0; i < Obstacles.Count; i++)
                {
                    if (Obstacles[i].HasState2)
                    {
                        //create obstacle to draw, that inherits everything from the obstacle instead of ID
                        Obstacles[i].State2Obstacle = new Util.Classes.ObstacleToDraw();
                        Obstacles[i].State2Obstacle.ObstacleID = Obstacles[i].ItemState2;//this is an id of obstacle from available obstacles that represents state2
                        Obstacles[i].State2Obstacle.Position = Obstacles[i].Position;
                        Obstacles[i].State2Obstacle.HasState2 = false;
                        Obstacles[i].State2Obstacle.CurrentState = -1;
                        Obstacles[i].State2Obstacle.State2Obstacle = null;
                    }

                    //if is interactive create tool icon
                    if (Obstacles[i].Interactive)
                    {
                        //get obstacle
                        o = LevelManager.GetObstacleByName(Obstacles[i].ObstacleID);

                        //create help rectangle
                        Obstacles[i].HelpRectangle = new Rectangle((int)Obstacles[i].Position.X - 40, (int)Obstacles[i].Position.Y - 40, o.Width+40, o.Height+40);

                        //create obstacle tool icon
                        toolIcon = new Util.Classes.ObstacleToolIcon();
                        toolIcon.IsActive = false;
                        toolIcon.MatherObstaclePos = Obstacles[i].Position;
                        toolIcon.Position = new Vector2((Obstacles[i].Position.X + o.Width)-20, (Obstacles[i].Position.Y + o.Height)-40);
                        toolIcon.ObstacleID = Obstacles[i].ObstacleID;
                        //assign it to the obstacle to draw
                        Obstacles[i].ToolIcon = toolIcon;
                        
                    }

                }



            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        #endregion

    }
}
